import 'dart:ffi';

import 'package:e_reception_flutter/common_widgets/common_list_page_widget/common_list_page_view_model.dart';
import 'package:e_reception_flutter/utils/screen_utils.dart';
import 'package:e_reception_flutter/utils/vg_http_utils.dart';
import 'package:e_reception_flutter/vg_widgets/vg_place_holder_status_widget/mixin/vg_place_holder_status_mixin.dart';
import 'package:e_reception_flutter/vg_widgets/vg_pull_to_refresh_widget/vg_pull_to_refresh_mixin.dart';
import 'package:e_reception_flutter/vg_widgets/vg_pull_to_refresh_widget/vg_pull_to_refresh_widget.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:vg_base/vg_arch_lib.dart';
import 'package:vg_base/vg_http_lib.dart';
import 'package:vg_base/vg_pull_to_refresh_lib.dart';
import 'package:vg_flutter_base_moudle/vg_moudle_widget_lib.dart';

typedef CommonListPageParseDataCallback<R> = R Function(VgHttpResponse resp);

typedef CommonListPageStateCallback<I, R extends BasePagerBean<I>> = void
    Function(CommonListPageWidgetState<I, R>);

typedef CommonListPageListCallback<I> = void Function(List<I> list);

typedef CommonListPageBuilder<I> = Widget Function(List<I> list);

typedef CommonListPagePlaceHolderBuilder<I> = Widget Function(
    List<I> list, Widget child, VoidCallback onRefresh);

typedef CommonListPageIndexedWidgetBuilder<I> = Widget Function(
    BuildContext context, int index, I itemBean);

typedef CommonListPageQueryMapCallback = Map<String, dynamic> Function(
    int page);

/// 通用分页请求列表组件
///
/// @author: zengxiangxi
/// @createTime: 2/22/21 11:11 AM
/// @specialDemand:
class CommonListPageWidget<I, R extends BasePagerBean<I>>
    extends StatefulWidget {
  ///请求类型
  final VgHttpType httpType;

  ///请求网址
  final String netUrl;

  ///请求Map
  final CommonListPageQueryMapCallback queryMapFunc;

  ///解析回调
  final CommonListPageParseDataCallback<R> parseDataFunc;

  ///列表自定义
  final CommonListPageBuilder<I> customListBuilder;

  ///列表项组件
  final CommonListPageIndexedWidgetBuilder<I> itemBuilder;

  ///分割线组件
  final CommonListPageIndexedWidgetBuilder<I> separatorBuilder;

  ///获取最新List列表值回调 (也可用CommonListPageStateCallback 拿到state.data 获取List)
  final CommonListPageListCallback<I> listFunc;

  ///启用下拉加载
  final bool enablePullDown;

  ///启用上拉更多
  final bool enablePullUp;

  ///是否初始化刷新 默认刷新
  final bool isInitRefresh;

  ///初始化initState时候 回调State引用
  final CommonListPageStateCallback<I, R> stateFunc;

  ///自定义判断是否显示占位框
  final CommonListPagePlaceHolderBuilder<I> placeHolderFunc;

  ///滚动控制器
  final ScrollController scrollController;

  ///ListView的cacheExtent值
  final double cacheExtent;

  ///自定义加载组件
  final Widget customloadingWidget;

  ///自定义空组件
  final Widget customEmptyWidget;

  ///自定义错误组件
  final Widget customErrorWidget;

  final bool needCache;
  final bool needCustomCache;

  final String cacheKey;

  final ScrollPhysics physics;

  ///是否需要底部安全距离
  final bool needBottomSaveWidget;
  ///底部额外距离
  final int bottomExtraHeight;

  const CommonListPageWidget(
      {Key key,
      @required this.httpType,
      @required this.netUrl,
      @required this.parseDataFunc,
      @required this.queryMapFunc,
      @required this.itemBuilder,
      this.separatorBuilder,
      this.customListBuilder,
      this.enablePullDown,
      this.enablePullUp,
      this.listFunc,
      this.isInitRefresh = true,
      this.stateFunc,
      this.placeHolderFunc,
      this.scrollController,
      this.cacheExtent,
      this.needCache,
      this.cacheKey,
      this.physics,
      this.customloadingWidget,
      this.customEmptyWidget,
      this.customErrorWidget,
      this.needCustomCache,
      this.needBottomSaveWidget,
      this.bottomExtraHeight
      })
      : assert(httpType != null),
        assert(isInitRefresh != null),
        assert(netUrl != null),
        assert(parseDataFunc != null),
        assert(itemBuilder != null),
        assert(queryMapFunc != null),
        super(key: key);

  @override
  CommonListPageWidgetState createState() => CommonListPageWidgetState<I, R>();
}

class CommonListPageWidgetState<I, R extends BasePagerBean<I>>
    extends BasePagerState<I, CommonListPageWidget<I, R>>
    with
        VgPlaceHolderStatusMixin,
        VgPullToRefreshMixin,
        AutomaticKeepAliveClientMixin {
  CommonListPageViewModel _viewModel;

  CommonListPageViewModel get viewModel => _viewModel;

  @override
  void initState() {
    super.initState();
    widget.stateFunc?.call(this);
    _viewModel = CommonListPageViewModel<I, R>(this,
        needCache: widget.needCache,
        cacheKey: widget.cacheKey,
        needCustomCache: widget.needCustomCache);
    if (widget?.isInitRefresh ?? true) {
      _viewModel.refresh();
    } else {
      isLoadingStatus = false;
      isEmptyStatus = true;
    }
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);
    if (widget.placeHolderFunc != null) {
      return widget.placeHolderFunc.call(data, _toPullRefreshWidget(), () {
        _viewModel.refresh();
      });
    }
    return MixinPlaceHolderStatusWidget(
        errorOnClick: () => _viewModel.refresh(),
        emptyOnClick: () => _viewModel.refresh(),
        emptyWidget: widget.customEmptyWidget,
        errorWidget:
            widget.needCache ?? false ? SizedBox() : widget.customErrorWidget,
        loadingWidget: widget.customloadingWidget,
        child: _toPullRefreshWidget());
  }

  Widget _toPullRefreshWidget() {
    return ScrollConfiguration(
      behavior: MyBehavior(),
      child: bindPullToRefresh(
        state: this,
        enablePullDown: widget.enablePullDown,
        enablePullUp: widget.enablePullUp,
        viewModel: _viewModel,
        child: widget?.customListBuilder?.call(data) ?? _toDefaultListWidget(),
      ),
    );
  }

  ///默认常规列表
  Widget _toDefaultListWidget() {
    return ListView.separated(
        controller: widget?.scrollController,
        itemCount: data?.length ?? 0,
        shrinkWrap: true,
        cacheExtent: widget.cacheExtent,
        padding: const EdgeInsets.all(0),
        physics: widget?.physics,
        keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag,
        itemBuilder: (BuildContext context, int index) {
          if(widget?.needBottomSaveWidget??false){
            if (index == ((data?.length ?? 0) - 1)) {
              return Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  widget?.itemBuilder
                      ?.call(context, index, data?.elementAt(index)) ??
                      SizedBox(height: 0),
                  _toBottomSaveWidget(),
                ],
              );
            } else {
              return widget?.itemBuilder
                  ?.call(context, index, data?.elementAt(index)) ??
                  SizedBox(height: 0);
            }
          }else{
            return widget?.itemBuilder
                ?.call(context, index, data?.elementAt(index)) ??
                SizedBox(height: 0);
          }
        },
        separatorBuilder: (BuildContext context, int index) {
          return widget?.separatorBuilder
                  ?.call(context, index, data?.elementAt(index)) ??
              SizedBox(height: 0);
        });
  }

  ///列表底部安全距离
  Widget _toBottomSaveWidget() {
    return Container(
      height: 50 + (widget?.bottomExtraHeight??0) + ScreenUtils.getBottomBarH(context),
    );
  }

  @override
  void setListData(List<I> list) {
    //更新后更新列表回调
    widget.listFunc?.call(list);
    super.setListData(list);
  }

  @override
  bool get wantKeepAlive => true;
}
